﻿/*
 * @Author: dadadaXU 1413107032@qq.com
 * @Date: 2025-02-14 15:04:45
 * @LastEditors: dadadaXU 1413107032@qq.com
 * @LastEditTime: 2025-02-15 16:11:03
 * @FilePath: /thread-pool/test/testThreadPool.cpp
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */

#include <chrono>
#include <thread>
#include <memory>
#include <gtest/gtest.h>
#include <iostream>
#include <string>

/* 测试类的私有成员 */
#ifdef GTEST_API_
#define private public
#define protected public
#endif

#include "../ThreadPool_pro/ThreadPool.hpp"

// class MyTask : public Task
// {
// public:
// 	MyTask(size_t a, size_t b)
// 		: a_(a) , b_(b) { }

// 	virtual Any run() override
// 	{
// 		std::this_thread::sleep_for(std::chrono::seconds(1));

// 		return a_ + b_;
// 	}

// private:
// 	size_t a_;
// 	size_t b_;
// };

class ThreadPoolTest : public ::testing::Test
{
protected:
    void TearDown() override
    {
        // Stop the thread pool after each test
        ThreadPool::instance().stop();
    }
};

TEST_F(ThreadPoolTest, SubmitTask)
{
    ThreadPool::instance().start(1);
    auto future = ThreadPool::instance().submitTask([]() -> int
                                                    { return 42; });
    EXPECT_EQ(future.get(), 42);
}

TEST_F(ThreadPoolTest, SubmitMultipleTasks)
{
    ThreadPool::instance().start(4);
    auto future1 = ThreadPool::instance().submitTask([]() -> double
                                                     { return 2.5; });
    auto future2 = ThreadPool::instance().submitTask([]() -> std::string
                                                     { return "hello world"; });

    struct ListNode
    {
        int val;
        ListNode *next;
        ListNode() : val(0), next(nullptr) {}
        ListNode(int x) : val(x), next(nullptr) {}
        ListNode(int x, ListNode *next) : val(x), next(next) {}
    };
    auto future3 = ThreadPool::instance().submitTask([]() -> ListNode
                                                     { return ListNode(3); });

    auto future4 = ThreadPool::instance().submitTask([]() -> long long
                                                     { return (long long)(99999) * 8080808 / 7; });

    EXPECT_EQ(future1.get(), 2.5);
    EXPECT_EQ(future2.get(), std::string("hello world"));
    EXPECT_EQ(future3.get().val, 3);
    EXPECT_EQ(future4.get(), (long long)(99999) * 8080808 / 7);
}

TEST_F(ThreadPoolTest, TaskQueueLimit)
{
    ThreadPool::instance().setTaskQueMaxThreshHold(2);
    ThreadPool::instance().start(2);

    auto future1 = ThreadPool::instance().submitTask([]()
                                                     { std::this_thread::sleep_for(std::chrono::seconds(10)); return 1; });
    auto future2 = ThreadPool::instance().submitTask([]()
                                                     { std::this_thread::sleep_for(std::chrono::seconds(10)); return 2; });
    ThreadPool::instance().submitTask([]()
                                      { std::this_thread::sleep_for(std::chrono::seconds(3)); });
    ThreadPool::instance().submitTask([]()
                                      { std::this_thread::sleep_for(std::chrono::seconds(3)); });

    /* 任务提交超时 返回默认空值 int() */
    auto future3 = ThreadPool::instance().submitTask([]() -> int
                                                     { return 3; });

    EXPECT_EQ(future1.get(), 1);
    EXPECT_EQ(future2.get(), 2);
    EXPECT_EQ(future3.get(), 0); // default int value is 0
}

TEST_F(ThreadPoolTest, CachedMode)
{
    ThreadPool::instance().setMode(PoolMode::MODE_CACHED);
    ThreadPool::instance().setTaskQueMaxThreshHold(10);
    ThreadPool::instance().start(2);

    for (int i = 0; i < 10; i++)
    {
        ThreadPool::instance().submitTask([]()
                                          { std::this_thread::sleep_for(std::chrono::seconds(3)); });
    }

    /* 等待线程自动回收 */
    std::this_thread::sleep_for(std::chrono::seconds(25));
}

int main(int argc, char **argv)
{
    ::testing::InitGoogleTest(&argc, argv);

    return RUN_ALL_TESTS();
}